LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY acces32b IS
  
  GENERIC (
    c_adresse_base : std_logic_vector(15 DOWNTO 0):=X"1300");  -- adresse de base du module

  PORT (
    clk          : IN  std_ulogic;
    reset        : IN  std_ulogic;

    adresse      : IN  std_logic_vector(15 DOWNTO 0);
    data_in      : IN  std_logic_vector(7 DOWNTO 0);
    data_out     : OUT std_logic_vector(7 DOWNTO 0);
    read         : IN  std_ulogic;
    write        : IN  std_ulogic;

    data_x       : IN  std_logic_vector(15 DOWNTO 0);
    data_y       : IN  std_logic_vector(15 DOWNTO 0);
    raz_data_lue : OUT bit;
    raz_data_done : IN bit;
	
    squal        : IN std_logic_vector(7 DOWNTO 0);
    raz_squal	 : OUT bit);

END acces32b;

ARCHITECTURE robotter OF acces32b IS

	SIGNAL s_data_x : std_logic_vector(15 downto 0);
	SIGNAL s_data_y : std_logic_vector(15 downto 0);
	SIGNAL s_squal : std_logic_vector(7 downto 0);
	SIGNAL s_latch_lock, s_latch_lock_synchrone : bit;
	
	SIGNAL s_raz_data_lue : bit;
	SIGNAL s_adresse_match : bit;
	
	SIGNAL s_read_precedent : std_ulogic;

BEGIN  -- robotter


  PROCESS(clk, reset) 
  BEGIN
	IF rising_edge(clk) THEN
--		IF v_read_precedent = '1' AND read = '0' THEN
		s_read_precedent <= read;
--		END IF;		
	END IF;
  END PROCESS;

  PROCESS(clk, reset, read, s_read_precedent, s_latch_lock) 
  BEGIN
	IF rising_edge(clk) THEN
		IF s_latch_lock = '1' THEN
			s_latch_lock_synchrone <= '1';
		ELSIF s_latch_lock ='0' and s_read_precedent = '0' AND read = '1' THEN
			s_latch_lock_synchrone <= '0';
		END IF;		
	END IF;
  END PROCESS;

	
	  s_data_x <= data_x WHEN s_read_precedent = '1' AND read = '0' AND s_latch_lock_synchrone = '0';
	  s_data_y <= data_y WHEN s_read_precedent = '1' AND read = '0';
	  s_squal <= squal WHEN s_read_precedent = '1' AND read = '0';

			
	s_adresse_match <= '1' WHEN adresse(15 DOWNTO 3) = c_adresse_base(15 DOWNTO 3)
				  ELSE '0';

	s_raz_data_lue <= '1' WHEN adresse(2 DOWNTO 0) =  "011" AND s_adresse_match = '1' ELSE '0';

  lecture: PROCESS (clk, adresse, data_in, read, data_x, data_y, squal)
	VARIABLE v_raz_data_lue : bit;
	VARIABLE v_raz_squal : bit;
	VARIABLE v_mem_lock : bit;
  BEGIN  
    IF s_adresse_match = '1' AND read = '0' THEN
      
	 CASE adresse(2 DOWNTO 0) IS
        WHEN "000" => data_out <= s_data_x(7 DOWNTO 0);
			s_latch_lock <= '1'; 

        WHEN "001" => data_out <= s_data_x(15 DOWNTO 8);
			s_latch_lock <= '0'; 
			
        WHEN "010" => data_out<= s_data_y(7 DOWNTO 0);

        WHEN "011" => data_out <= s_data_y(15 DOWNTO 8);
											
        WHEN "100" => data_out <= s_squal;
					v_raz_squal := '1';
						
        WHEN OTHERS => NULL;
      END CASE;
	
	ELSIF v_raz_squal = '1' THEN
	  v_raz_squal := '0';
	  raz_squal <= '1';
	  data_out <= (OTHERS => '0');

	ELSE
      data_out <= (OTHERS => '0');
	  raz_squal <= '0';
	 -- s_raz_data_lue <= '0';
	
    END IF;
  END PROCESS lecture;



	PROCESS(clk, reset, s_raz_data_lue, read, raz_data_done)
		VARIABLE v_mem : bit;
	BEGIN
		IF rising_edge(clk) THEN
			
			IF s_raz_data_lue = '1' THEN
				v_mem := '1';
			
			ELSIF read = '1' and v_mem = '1' THEN
				v_mem := '0';
				raz_data_lue <= '1';
			
			ELSIF raz_data_done = '1'  THEN
				raz_data_lue <= '0';
				
			END IF;
			
		END IF;
	END PROCESS;


END robotter;
